package gui;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import framework.ImageWrapper;
import framework.ResourcesWrapper;
import gamebackend.Block;
import gamebackend.Block.NeighborState;

/**
 * Holds the images to be used on Blocks.  Images must
 * end with ".png".
 * @author Caddey
 *
 */
public class BlockStyle {

	/*
	 * I really don't like having these as static constants
	 * ever since I had to have an initiate method,
	 * but changing all of my code would be a pain.
	 */
	public static final BlockStyle PLAIN = new BlockStyle(null, false);
	public static final BlockStyle THORN = new BlockStyle("thorn", true);
	public static final BlockStyle ASTEROID = new BlockStyle("asteroid", true);
	public static final BlockStyle METAL = new BlockStyle("metal", true);
	
	private final String my_prefix;
	private final boolean my_hasDamaged;
	private Map<String, ImageWrapper> my_images;
	private Map<String, Integer> my_variations;
	public BlockStyle(final String the_prefix, final boolean the_hasDamaged) {

		my_prefix = the_prefix;
		my_hasDamaged = the_hasDamaged;
			
		
	}
	/**
	 * This must be called before preparing any blocks.
	 * @param the_resources
	 */
	public void initialize(ResourcesWrapper the_resources) {
		if (my_prefix == null) {
			return;
		}
		my_images = new HashMap<String, ImageWrapper>();
		my_variations = new HashMap<String, Integer>();
		final String[] names;
		if (my_hasDamaged) {
			names = new String[]{"oo", "ox", "xo", "xx", "od", "do", "dd", "dx", "xd"};
		} else {
			names = new String[]{"oo", "ox", "xo", "xx"};
		}
		for (String name : names) {
			my_images.put(name + "1", loadImage(the_resources, name));
			int variation = 1;
			boolean more = true;
			while (more) {
				variation++;
				try {
					my_images.put(name + variation, loadImage(the_resources, name + "_" + variation));
				} catch (IllegalArgumentException e) {
					more = false;
				}
				
				
			}
			variation--;
			
			
			
			my_variations.put(name, variation);
		}
	}
	/**
	 * @param the_name without prefix or .png.  For example,
	 * "asteroid_ox_2.png" should just be "ox_2".
	 * @return
	 */
	private ImageWrapper loadImage(final ResourcesWrapper the_resources,
			final String the_name) {
		return the_resources.loadImage(my_prefix + "_" + the_name + ".png");
	}
	
	
	public void prepare(Block block) {
		/*
		 * Currently prepare is called when a block is damaged.  The previous variation is
		 * not taken into account.
		 */
		if (my_prefix == null) {
			return;
		}
		if (my_images == null) {
			throw new IllegalStateException("initialize must be invoked before prepare");
		}
		final ImageWrapper TL, TR, BR, BL;
		String name;
		
		name = getLetter(block.getNeighborState(3));
		name += getLetter(block.getNeighborState(0));
		TL = getVariation(name);
		
		name = getLetter(block.getNeighborState(1));
		name += getLetter(block.getNeighborState(0));
		TR = getVariation(name);
		
		name = getLetter(block.getNeighborState(1));
		name += getLetter(block.getNeighborState(2));
		BR = getVariation(name);
		
		name = getLetter(block.getNeighborState(3));
		name += getLetter(block.getNeighborState(2));
		BL = getVariation(name);
		
		
		
		block.setImages(new ImageWrapper[]{TL, TR, BR, BL});
		
	}
	private String getLetter(final NeighborState the_state) {
		switch (the_state) {
		case FULL:
			return "o";
		case EMPTY:
			return "x";
		case DESTROYED:
			if (my_hasDamaged) {
				return "d";
			}
			return "x";
				
		}
		return null;
	}
	private ImageWrapper getVariation(String name) {
		int use = (int) (Math.random() * my_variations.get(name)) + 1;
		return my_images.get(name + use);
	}
	public void dispose() {
		if (my_images != null) {
			for (ImageWrapper image : my_images.values()) {
				image.dispose();
			}
		}
		my_images.clear();
	}
}
